package factory

import (
	"github.com/pkg/errors"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/columnd"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/infod"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/interactiond"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/core/reviewd"
	"gogs.xiaoyuanjijiehao.com/antlinker/antcms/ddd"
)

var (
	// DefaultFactory 默认工厂
	DefaultFactory Factory
)

// Factory 工厂方法
type Factory interface {
	GetOrCreIGroup(ctx ddd.Context, targetType interactiond.IGTargetType, targetID string) (*interactiond.GroupAggregate, error)
	// ReviewOK 审核通过
	ReviewOK(ctx ddd.Context, targetType int, targetID, reason, reviewer string) error
	// 审核不通过
	ReviewNo(ctx ddd.Context, targetType int, targetID, reason, reviewer string) error
}

// Init 初始化默认工厂方法
func Init(d ddd.Domain) {
	DefaultFactory = newFactory(d)
}

// newFactory 获取工厂方法
func newFactory(d ddd.Domain) Factory {
	return &factory{
		d:        d,
		rar:      d.SubDomain(interactiond.DomainID).AggregateRootByID(interactiond.Replay).(interactiond.ReplayAggregateRoot),
		igar:     d.SubDomain(interactiond.DomainID).AggregateRootByID(interactiond.Group).(interactiond.GroupAggregateRoot),
		iiar:     d.SubDomain(interactiond.DomainID).AggregateRootByID(interactiond.Interaction).(interactiond.InteractionAggregateRoot),
		iar:      d.SubDomain(infod.DomainID).AggregateRootByID(infod.DomainID).(infod.InfoAggregateRoot),
		reviewar: d.SubDomain(reviewd.DomainID).AggregateRootByID(reviewd.DomainID).(reviewd.ReviewAggregateRoot),
		car:      d.SubDomain(columnd.DomainID).AggregateRootByID(columnd.DomainID).(columnd.ColumnAggregateRoot),
	}
}

type factory struct {
	d        ddd.Domain
	iar      infod.InfoAggregateRoot
	reviewar reviewd.ReviewAggregateRoot
	car      columnd.ColumnAggregateRoot
	rar      interactiond.ReplayAggregateRoot
	igar     interactiond.GroupAggregateRoot
	iiar     interactiond.InteractionAggregateRoot
}

// GetOrCreIGroup 创建或获取互动组
func (f factory) GetOrCreIGroup(dctx ddd.Context, targetType interactiond.IGTargetType, targetID string) (*interactiond.GroupAggregate, error) {
	g, err := f.igar.GetIGroup2(dctx, targetType, targetID)
	if err != nil {
		return nil, errors.Wrapf(err, "查询互动目标(%d-%v)失败", targetType, targetID)

	}
	if g != nil {
		return g, nil
	}
	ctrl, err := f.getForGroupCtrl(dctx, targetType, targetID)
	if err != nil {
		return nil, err
	}
	id, err := f.igar.CreGroup(dctx, interactiond.GroupDesc{
		TargetID:   targetID,
		TargetType: targetType,
	}, *ctrl)
	if err != nil {
		return nil, err
	}
	return f.igar.GetGroup(dctx, id)
}
func (f factory) getForGroupCtrl(dctx ddd.Context, targetType interactiond.IGTargetType, targetID string) (*interactiond.GroupCtrl, error) {
	// TODO: 只实现了信息的互动组创建，没有实现其他的互动组创建，有需要需要继续实现其中的控制代码
	switch targetType {
	case interactiond.IGTTInfo:
		return f.getInfoForGroupCtrl(dctx, targetID)
	case interactiond.IGTTColumn:
		return f.getColumnForGroupCtrl(dctx, targetID)
	case interactiond.IGTTPerson:
		return f.getPersonForGroupCtrl(dctx, targetID)
	case interactiond.IGTTReplay:
		// TODO: 临时写死，还没有评论的互动管理配置
		return &interactiond.GroupCtrl{
			Status:      interactiond.IGStatusNormal,
			IsReplay:    1,
			IsReplayChk: 0,
			AllowCodes:  []string{"like"},
		}, nil
	default:
		return &interactiond.GroupCtrl{
			Status:      interactiond.IGStatusNormal,
			IsReplay:    1,
			IsReplayChk: 0,
		}, nil
	}
}
func (f factory) getColumnForGroupCtrl(dctx ddd.Context, targetID string) (*interactiond.GroupCtrl, error) {
	col, err := f.car.GetColumn(dctx, targetID)
	if err != nil {
		return nil, errors.Wrapf(err, "查询栏目(%v)失败", targetID)
	}
	if col == nil {
		return nil, errors.Errorf("栏目(%v)不存在", targetID)
	}
	return &interactiond.GroupCtrl{
		Status:      interactiond.IGStatusNormal,
		IsReplay:    col.IsColReply,
		IsReplayChk: col.IsChk,
		AllowCodes:  col.AllowIntCode,
	}, nil
}
func (f factory) getInfoForGroupCtrl(dctx ddd.Context, targetID string) (*interactiond.GroupCtrl, error) {
	i, err := f.iar.GetInfo(dctx, targetID)
	if err != nil {
		return nil, errors.Wrapf(err, "查询信息(%v)失败", targetID)
	}
	if i == nil {
		return nil, errors.Errorf("信息(%v)不存在", targetID)
	}
	col, err := f.car.GetColumn(dctx, i.ColumnID)
	if err != nil {
		return nil, errors.Errorf("栏目(%v)不存在", i.ColumnID)
	}
	if col == nil {
		return nil, errors.New("信息所在栏目不存在，不能评论")
	}
	return &interactiond.GroupCtrl{
		Status:      interactiond.IGStatusNormal,
		IsReplay:    col.IsReply,
		IsReplayChk: col.IsChk,
		AllowCodes:  col.AllowIntCode,
	}, nil
}
func (f factory) getPersonForGroupCtrl(dctx ddd.Context, targetID string) (*interactiond.GroupCtrl, error) {
	// TODO: 这里的信息缺少管理还没有实现
	return &interactiond.GroupCtrl{
		Status:      interactiond.IGStatusNormal,
		IsReplay:    0,
		IsReplayChk: 0,
		AllowCodes:  []string{"follow"},
	}, nil
}
